/* 
 * Simple average sampling of an analog pin for testing with water dropping on
 * leads.
 *
 * $AUTHOR$  Reuben Smith (smithre5)
 * $COURSE$  ECE 387, Spring 2013
 * $TEACHER$ Dr. Peter Jamieson
 *
 */
 
/* TODO
 * 	Grounded voltage divider for the actual circuit so there's a reference
 *		point on the samples. Otherwise we'll keep getting the 
 * 		oscillation from 0 to 5 V when the circuit isn't closed.
 */

const int    SERIAL_RATE      = 9600;                // baud
const int    SAMPLE_READ_PIN  = A0;                  	// analog pins only!
const int    SAMPLE_COUNT     = 500;                 	// samples / s
const int    SAMPLE_COUNT_QTR = SAMPLE_COUNT >> 2;   	// samples / s
const int    SAMPLE_RATE      = 1000000 / SAMPLE_COUNT; // us
const float  SAMPLE_CONV      = 5.0f / 1023;         	// [0, 1023] -> [0f, 5f]

int raw_samples[SAMPLE_COUNT] = { 0 };
int current_sample = 0;


void setup()
{
  Serial.begin(SERIAL_RATE);
}


void loop()
{
  raw_samples[current_sample] = analogRead(SAMPLE_READ_PIN);  
  ++current_sample;
 
  // smithre5: This is just to get four prints per sampling period to allow
  // we meager humans to see what's happening.
  if (current_sample % SAMPLE_COUNT_QTR == 0) {
    Serial.println(get_average(raw_samples, SAMPLE_COUNT) * SAMPLE_CONV);
  }
  
  if (current_sample == SAMPLE_COUNT) {
    current_sample = 0;
  }
  
  delayMicroseconds(SAMPLE_RATE);
}


/* get_average
 * -> values      values to be averaged
 * -> count       number of values
 * <- fp average of values
 *
 * Returns a floating-point average of the values given.
 */
float get_average(const int* values, int count)
{
  // smithre5: int here would wrap around; keep this long.
  long average = 0;
  
  for (int i = count; --i >= 0;) {
    average = average + values[i];
  }
  
  return (float)average / (float)count;
}
